package com.cennavi.bigdata.baotou.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cennavi.bigdata.baotou.dao.IndexDao;
import com.cennavi.bigdata.baotou.service.IndexService;
import com.cennavi.bigdata.baotou.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by cennavi on 2018/10/15.
 */
@Service
public class IndexServiceImpl implements IndexService {

    private static final Logger LOGGER = LoggerFactory.getLogger(IndexServiceImpl.class);

    @Autowired
    private IndexDao indexDao;

    @Override
    public List<Map<String, Object>> listArea() {
        return indexDao.listArea();
    }

    @Override
    public List<Map<String, Object>> DgListSpeedIndexByDay(String id, String startTime1, String endTime1) {

        List<Map<String,Object>> startlist =  indexDao.DgListSpeedIndexByDay(id,startTime1);
        List<Map<String,Object>> endlist = indexDao.DgListSpeedIndexByDay(id,endTime1);

        Map<String,Object> startmap = startlist!=null?spotPrimingList(startlist,null):new HashMap<String, Object>();
        Map<String,Object> endmap = endlist!=null?spotPrimingList(endlist,endTime1):new HashMap<String, Object>();

        startmap.put("id",id);
        startmap.put("time",startTime1);
        endmap.put("id",id);
        endmap.put("time",endTime1);
        List<Map<String, Object>> list = new ArrayList<>();
        list.add(startmap);
        list.add(endmap);
        return list;
    }

    /**
     * 填补空缺数据
     * @param startlist
     * @return
     */
    private Map<String, Object> spotPrimingList(List<Map<String, Object>> startlist,String time) {

        Map<String, Object> map = new HashMap<>();

        List<JSONObject> indexList = new ArrayList<>();
        List<JSONObject> speedList = new ArrayList<>();
        int count = 0;
        String dateStr = DateUtils.DateFormatUnit.DAY_AND_HOUR.getDateStr(new Date());
        if (time !=null&&(time.replaceAll("-","").equals(dateStr.substring(0,8)))){
            for (int i = 0; i < Integer.valueOf(dateStr.substring(8)); i++) {
                JSONObject indexjson = new JSONObject();
                JSONObject speedjson = new JSONObject();
                for (int j = 0; j < startlist.size(); j++) {
                    int hour = Integer.valueOf(startlist.get(j).get("hour").toString());
                    if (hour==i){
                        indexjson.put(hour+":00",startlist.get(j).get("avgindex").toString());
                        speedjson.put(hour+":00",startlist.get(j).get("avgspeed").toString());
                        indexList.add(indexjson);
                        speedList.add(speedjson);
                        count++;
                    }
                }
                if (count==i){
                    if (i<10){
                        indexjson.put("0"+i+":00",0.0);
                        speedjson.put("0"+i+":00",0.0);
                    }else {
                        indexjson.put(i+":00",0.0);
                        speedjson.put(i+":00",0.0);
                    }
                    indexList.add(indexjson);
                    speedList.add(speedjson);
                    count++;
                }
            }
        }else {
            for (int i = 0; i < 24; i++) {
                JSONObject indexjson = new JSONObject();
                JSONObject speedjson = new JSONObject();
                for (int j = 0; j < startlist.size(); j++) {
                    int hour = Integer.valueOf(startlist.get(j).get("hour").toString());
                    if (hour==i){
                        indexjson.put(hour+":00",startlist.get(j).get("avgindex").toString());
                        speedjson.put(hour+":00",startlist.get(j).get("avgspeed").toString());
                        indexList.add(indexjson);
                        speedList.add(speedjson);
                        count++;
                    }
                }
                if (count==i){
                    if (i<10){
                        indexjson.put("0"+i+":00",0.0);
                        speedjson.put("0"+i+":00",0.0);
                    }else {
                        indexjson.put(i+":00",0.0);
                        speedjson.put(i+":00",0.0);
                    }
                    indexList.add(indexjson);
                    speedList.add(speedjson);
                    count++;
                }
            }
        }

        map.put("avgindexs",indexList);
        map.put("avgspeeds",speedList);
        return map;
    }

    @Override
    public List<Map<String, Object>> searchRoadByName(String roadname) {
        return indexDao.searchRoadByName(roadname);
    }

    @Override
    public List<Map<String, Object>> dataListSpeedIndex(String id,  String startTime1,String endTime1, String type) {
        List<Map<String,Object>> list = null;
        if (type.equals("1")){//区域
             list = indexDao.dataListSpeedIndexArea(id,startTime1.replaceAll("-",""),endTime1.replaceAll("-",""));
        }else {//道路
             list = indexDao.dataListSpeedIndex(id,startTime1.replaceAll("-",""),endTime1.replaceAll("-",""));
        }
        DecimalFormat decimalFormat = new DecimalFormat("#.###");
        List<Map<String, Object>> maps = makeSpeedIndexList(list,decimalFormat);
        return maps;
    }

    @Override
    public List<Map<String, Object>> DgListSpeedIndexByWeek(String id, String startTime1, String endTime1, String startTime2, String endTime2) {

        List<Map<String,Object>> startList = indexDao.DgListSpeedIndexByWeek(id,startTime1,endTime1);
        List<Map<String,Object>> endList = indexDao.DgListSpeedIndexByWeek(id,startTime2,endTime2);

        Map<String, Object> startmap = startList!=null?spotPrimingList(startList,null):new HashMap<String, Object>();
        Map<String, Object> endmap = endList!=null?spotPrimingList(endList,null):new HashMap<String, Object>();

        startmap.put("id",id);
        startmap.put("time",startTime1+" "+endTime1);
        endmap.put("id",id);
        endmap.put("time",startTime2+" "+endTime2);

        List<Map<String, Object>> list = new ArrayList<>();
        list.add(startmap);
        list.add(endmap);

        return list;
    }

    @Override
    public List<Map<String, Object>> listQuarterOfYear() {
        return indexDao.listQuarterOfYear();
    }

    @Override
    public List<Map<String, Object>> DgListSpeedIndexByQuarter(String id, String startTime1, String endTime1) {

        List<Map<String,Object>> startList = indexDao.DgListSpeedIndexByQuarter(id,startTime1);
        List<Map<String,Object>> endList = indexDao.DgListSpeedIndexByQuarter(id,endTime1);

        Map<String, Object> startmap = startList!=null?spotPrimingList(startList,null):new HashMap<String, Object>();
        Map<String, Object> endmap = endList!=null?spotPrimingList(endList,null):new HashMap<String, Object>();

        startmap.put("id",id);
        startmap.put("time",startTime1);
        endmap.put("id",id);
        endmap.put("time",endTime1);

        List<Map<String, Object>> list = new ArrayList<>();
        list.add(startmap);
        list.add(endmap);

        return list;
    }

    @Override
    public List<Map<String, Object>> dataListSpeedIndexByWeek(String id, String startTime1, String endTime1,String startTime2, String endTime2, String type) {

        List<Map<String,Object>> list_1 = null;
        List<Map<String,Object>> list_2 = null;
        if (type.equals("1")){//区域
            list_1 = indexDao.dataListSpeedIndexAreaWeek(id,startTime1.replaceAll("-",""),endTime1.replaceAll("-",""));
            list_2 = indexDao.dataListSpeedIndexAreaWeek(id,startTime2.replaceAll("-",""),endTime2.replaceAll("-",""));
        }else {//道路
            list_1 = indexDao.dataListSpeedIndexRoadWeek(id,startTime1.replaceAll("-",""),endTime1.replaceAll("-",""));
            list_2 = indexDao.dataListSpeedIndexRoadWeek(id,startTime2.replaceAll("-",""),endTime2.replaceAll("-",""));
        }
        DecimalFormat decimalFormat = new DecimalFormat("#.###");
        List<Map<String, Object>> maps = makeSpeedIndexListWeek(list_1,list_2,decimalFormat,startTime1,endTime1,startTime2,endTime2);
        return maps;
    }

    @Override
    public List<Map<String, Object>> dataListSpeedIndexByQuarter(String id, String startTime1, String endTime1, String type) {
        List<Map<String,Object>> list_1 = null;
        List<Map<String,Object>> list_2 = null;
        if (type.equals("1")){//区域
            list_1 = indexDao.dataListSpeedIndexAreaQuarter(id,startTime1.replaceAll("-",""));
            list_2 = indexDao.dataListSpeedIndexAreaQuarter(id,endTime1.replaceAll("-",""));
        }else {//道路
            list_1 = indexDao.dataListSpeedIndexRoadQuarter(id,startTime1.replaceAll("-",""));
            list_2 = indexDao.dataListSpeedIndexRoadQuarter(id,endTime1.replaceAll("-",""));
        }
        DecimalFormat decimalFormat = new DecimalFormat("#.###");
        List<Map<String, Object>> maps = makeSpeedIndexListQuarter(list_1,list_2,decimalFormat,startTime1,endTime1);
        return maps;
    }

    @Override
    public List<Map<String, Object>> dataListRoadPredict(String timeType, String roadid,short iswork) {
        String dateStr = null;
        if (timeType.equals("1")){
            dateStr = DateUtils.DateFormatUnit.SHORT_HOUR_MINE.getDateStr(DateUtils.getTimeMinuteByDate(DateUtils.addHour(new Date(), 1)));
        }else {
            dateStr = DateUtils.DateFormatUnit.SHORT_HOUR_MINE.getDateStr(DateUtils.getTimeMinuteByDate(DateUtils.addMinute(new Date(), Integer.valueOf(timeType))));
        }
        List<Map<String, Object>> list = indexDao.dataListRoadPredict(roadid,dateStr,iswork);
        for (Map<String, Object> map : list) {
            double avgindex = Double.valueOf(map.get("index").toString());
            if (avgindex >= 0 && avgindex < 2) {
                map.put("trafficIntensity", "一级");
            } else if (avgindex >= 2 && avgindex < 4) {
                map.put("trafficIntensity", "二级");
            } else if (avgindex >= 4 && avgindex < 6) {
                map.put("trafficIntensity", "三级");
            } else if (avgindex >= 6 && avgindex < 8) {
                map.put("trafficIntensity","四级");
            } else if (avgindex >= 8) {
                map.put("trafficIntensity", "五级");
            }
            map.remove("index");
        }
        return list;
    }

    private List<Map<String, Object>> makeSpeedIndexListQuarter(List<Map<String, Object>> list_1, List<Map<String, Object>> list_2, DecimalFormat decimalFormat, String startTime1, String endTime1) {
        List<Map<String, Object>> maps = new ArrayList<>();
        //开始时间详情
        String timeA = startTime1.substring(0,4)+"年 第"+Integer.valueOf(startTime1.substring(4))+"季度";
        //结束时间详情
        String timeB = endTime1.substring(0,4)+"年 第"+Integer.valueOf(endTime1.substring(4))+"季度";
        //平均速度
        double avgspeed1 = Double.valueOf(list_2.get(0).get("avgspeed").toString());
        double avgspeed0 = Double.valueOf(list_1.get(0).get("avgspeed").toString());
        String avgspeedResult = decimalFormat.format((avgspeed1-avgspeed0)*100/(avgspeed0==0.0?1:avgspeed0))+"%";
        //最大速度、最小速度
        double maxspeed1 = Double.valueOf(list_2.get(0).get("maxspeed").toString());
        double maxspeed0 = Double.valueOf(list_1.get(0).get("maxspeed").toString());
        String maxspeedResult = decimalFormat.format((maxspeed1-maxspeed0)*100/(maxspeed0==0.0?1:maxspeed0))+"%";

        double minspeed1 = Double.valueOf(list_2.get(0).get("minspeed").toString());
        double minspeed0 = Double.valueOf(list_1.get(0).get("minspeed").toString());
        String minspeedResult = decimalFormat.format((minspeed1-minspeed0)*100/(minspeed0==0.0?1:minspeed0))+"%";
        //平均指数
        double avgindex1 = Double.valueOf(list_2.get(0).get("avgindex").toString());
        double avgindex0 = Double.valueOf(list_1.get(0).get("avgindex").toString());
        String avgindexResult = decimalFormat.format((avgindex1-avgindex0)*100/(avgindex0==0.0?1:avgindex0))+"%";
        //最大最小指数
        double maxindex1 = Double.valueOf(list_2.get(0).get("maxindex").toString());
        double maxindex0 = Double.valueOf(list_1.get(0).get("maxindex").toString());
        String maxindexResult = decimalFormat.format((maxindex1-maxindex0)*100/(maxindex0==0.0?1:maxindex0))+"%";

        double minindex1 = Double.valueOf(list_2.get(0).get("minindex").toString());
        double minindex0 = Double.valueOf(list_1.get(0).get("minindex").toString());
        String minindexResult = decimalFormat.format((minindex1-minindex0)*100/(minindex0==0.0?1:minindex0))+"%";
        //平均旅行时间
        double avgtraveltime1 = Double.valueOf(list_2.get(0).get("avgtraveltime").toString());
        double avgtraveltime0 = Double.valueOf(list_1.get(0).get("avgtraveltime").toString());
        String avgtraveltimeResult = decimalFormat.format((avgtraveltime1-avgtraveltime0)*100/(avgtraveltime0==0.0?1:avgtraveltime0))+"%";
        Map<String, Object> map_1 = new HashMap<>();
        Map<String, Object> map_2 = new HashMap<>();
        Map<String, Object> map_3 = new HashMap<>();

        map_1.put("time",timeA);
        map_1.put("avgspeed",avgspeed0);
        map_1.put("maxminspeed",maxspeed0+" & "+minspeed0);
        map_1.put("avgindex",avgindex0);
        map_1.put("maxminindex",maxindex0+" & "+minindex0);
        map_1.put("avgtraveltime",avgtraveltime0);
        map_1.put("id",list_1.get(0).get("id").toString());
        map_1.put("name",list_1.get(0).get("name").toString());

        map_2.put("time",timeB);
        map_2.put("avgspeed",avgspeed1);
        map_2.put("maxminspeed",maxspeed1+" & "+minspeed1);
        map_2.put("avgindex",avgindex1);
        map_2.put("maxminindex",maxindex1+" & "+minindex1);
        map_2.put("avgtraveltime",avgtraveltime1);
        map_2.put("id",list_2.get(0).get("id").toString());
        map_2.put("name",list_2.get(0).get("name").toString());

        map_3.put("time","对比结果");
        map_3.put("avgspeed",avgspeedResult);
        map_3.put("maxminspeed",maxspeedResult+" & "+minspeedResult);
        map_3.put("avgindex",avgindexResult);
        map_3.put("maxminindex",maxindexResult+" & "+minindexResult);
        map_3.put("avgtraveltime",avgtraveltimeResult);
        map_3.put("name",list_2.get(0).get("name").toString());

        maps.add(map_1);
        maps.add(map_2);
        maps.add(map_3);
        return maps;
    }


    private List<Map<String, Object>> makeSpeedIndexListWeek(List<Map<String, Object>> list_1, List<Map<String, Object>> list_2, DecimalFormat decimalFormat, String startTime1, String endTime1, String startTime2, String endTime2) {
        List<Map<String, Object>> maps = new ArrayList<>();
        //开始时间详情
        String timeA = startTime1+"-->"+endTime1;
        //结束时间详情
        String timeB = startTime2+"-->"+endTime2;
        //平均速度
        double avgspeed1 = Double.valueOf(list_2.get(0).get("avgspeed").toString());
        double avgspeed0 = Double.valueOf(list_1.get(0).get("avgspeed").toString());
        String avgspeedResult = decimalFormat.format((avgspeed1-avgspeed0)*100/(avgspeed0==0.0?1:avgspeed0))+"%";
        //最大速度、最小速度
        double maxspeed1 = Double.valueOf(list_2.get(0).get("maxspeed").toString());
        double maxspeed0 = Double.valueOf(list_1.get(0).get("maxspeed").toString());
        String maxspeedResult = decimalFormat.format((maxspeed1-maxspeed0)*100/(maxspeed0==0.0?1:maxspeed0))+"%";

        double minspeed1 = Double.valueOf(list_2.get(0).get("minspeed").toString());
        double minspeed0 = Double.valueOf(list_1.get(0).get("minspeed").toString());
        String minspeedResult = decimalFormat.format((minspeed1-minspeed0)*100/(minspeed0==0.0?1:minspeed0))+"%";
        //平均指数
        double avgindex1 = Double.valueOf(list_2.get(0).get("avgindex").toString());
        double avgindex0 = Double.valueOf(list_1.get(0).get("avgindex").toString());
        String avgindexResult = decimalFormat.format((avgindex1-avgindex0)*100/(avgindex0==0.0?1:avgindex0))+"%";
        //最大最小指数
        double maxindex1 = Double.valueOf(list_2.get(0).get("maxindex").toString());
        double maxindex0 = Double.valueOf(list_1.get(0).get("maxindex").toString());
        String maxindexResult = decimalFormat.format((maxindex1-maxindex0)*100/(maxindex0==0.0?1:maxindex0))+"%";

        double minindex1 = Double.valueOf(list_2.get(0).get("minindex").toString());
        double minindex0 = Double.valueOf(list_1.get(0).get("minindex").toString());
        String minindexResult = decimalFormat.format((minindex1-minindex0)*100/(minindex0==0.0?1:minindex0))+"%";
        //平均旅行时间
        double avgtraveltime1 = Double.valueOf(list_2.get(0).get("avgtraveltime").toString());
        double avgtraveltime0 = Double.valueOf(list_1.get(0).get("avgtraveltime").toString());
        String avgtraveltimeResult = decimalFormat.format((avgtraveltime1-avgtraveltime0)*100/(avgtraveltime0==0.0?1:avgtraveltime0))+"%";
        Map<String, Object> map_1 = new HashMap<>();
        Map<String, Object> map_2 = new HashMap<>();
        Map<String, Object> map_3 = new HashMap<>();

        map_1.put("time",timeA);
        map_1.put("avgspeed",avgspeed0);
        map_1.put("maxminspeed",maxspeed0+" & "+minspeed0);
        map_1.put("avgindex",avgindex0);
        map_1.put("maxminindex",maxindex0+" & "+minindex0);
        map_1.put("avgtraveltime",avgtraveltime0);
        map_1.put("id",list_1.get(0).get("id").toString());
        map_1.put("name",list_1.get(0).get("name").toString());

        map_2.put("time",timeB);
        map_2.put("avgspeed",avgspeed1);
        map_2.put("maxminspeed",maxspeed1+" & "+minspeed1);
        map_2.put("avgindex",avgindex1);
        map_2.put("maxminindex",maxindex1+" & "+minindex1);
        map_2.put("avgtraveltime",avgtraveltime1);
        map_2.put("id",list_2.get(0).get("id").toString());
        map_2.put("name",list_2.get(0).get("name").toString());

        map_3.put("time","对比结果");
        map_3.put("avgspeed",avgspeedResult);
        map_3.put("maxminspeed",maxspeedResult+" & "+minspeedResult);
        map_3.put("avgindex",avgindexResult);
        map_3.put("maxminindex",maxindexResult+" & "+minindexResult);
        map_3.put("avgtraveltime",avgtraveltimeResult);
        map_3.put("name",list_2.get(0).get("name").toString());

        maps.add(map_1);
        maps.add(map_2);
        maps.add(map_3);
        return maps;
    }



    private List<Map<String, Object>> makeSpeedIndexList(List<Map<String, Object>> list, DecimalFormat decimalFormat) {

        List<Map<String, Object>> maps = new ArrayList<>();
        //开始时间详情
        String timeA = list.get(0).get("time").toString();
        timeA = timeA.substring(0,4)+"-"+timeA.substring(4,6)+"-"+timeA.substring(6);
        //结束时间详情
        String timeB = list.get(1).get("time").toString();
        timeB = timeB.substring(0,4)+"-"+timeB.substring(4,6)+"-"+timeB.substring(6);
        //平均速度
        double avgspeed1 = Double.valueOf(list.get(1).get("avgspeed").toString());
        double avgspeed0 = Double.valueOf(list.get(0).get("avgspeed").toString());
        String avgspeedResult = decimalFormat.format((avgspeed1-avgspeed0)*100/(avgspeed0==0.0?1:avgspeed0))+"%";
        //最大速度、最小速度
        double maxspeed1 = Double.valueOf(list.get(1).get("maxspeed").toString());
        double maxspeed0 = Double.valueOf(list.get(0).get("maxspeed").toString());
        String maxspeedResult = decimalFormat.format((maxspeed1-maxspeed0)*100/(maxspeed0==0.0?1:maxspeed0))+"%";

        double minspeed1 = Double.valueOf(list.get(1).get("minspeed").toString());
        double minspeed0 = Double.valueOf(list.get(0).get("minspeed").toString());
        String minspeedResult = decimalFormat.format((minspeed1-minspeed0)*100/(minspeed0==0.0?1:minspeed0))+"%";
        //平均指数
        double avgindex1 = Double.valueOf(list.get(1).get("avgindex").toString());
        double avgindex0 = Double.valueOf(list.get(0).get("avgindex").toString());
        String avgindexResult = decimalFormat.format((avgindex1-avgindex0)*100/(avgindex0==0.0?1:avgindex0))+"%";
        //最大最小指数
        double maxindex1 = Double.valueOf(list.get(1).get("maxindex").toString());
        double maxindex0 = Double.valueOf(list.get(0).get("maxindex").toString());
        String maxindexResult = decimalFormat.format((maxindex1-maxindex0)*100/(maxindex0==0.0?1:maxindex0))+"%";

        double minindex1 = Double.valueOf(list.get(1).get("minindex").toString());
        double minindex0 = Double.valueOf(list.get(0).get("minindex").toString());
        String minindexResult = decimalFormat.format((minindex1-minindex0)*100/(minindex0==0.0?1:minindex0))+"%";
        //平均旅行时间
        double avgtraveltime1 = Double.valueOf(list.get(1).get("avgtraveltime").toString());
        double avgtraveltime0 = Double.valueOf(list.get(0).get("avgtraveltime").toString());
        String avgtraveltimeResult = decimalFormat.format((avgtraveltime1-avgtraveltime0)*100/(avgtraveltime0==0.0?1:avgtraveltime0))+"%";
        Map<String, Object> map_1 = new HashMap<>();
        Map<String, Object> map_2 = new HashMap<>();
        Map<String, Object> map_3 = new HashMap<>();

        map_1.put("time",timeA);
        map_1.put("avgspeed",avgspeed0);
        map_1.put("maxminspeed",maxspeed0+" & "+minspeed0);
        map_1.put("avgindex",avgindex0);
        map_1.put("maxminindex",maxindex0+" & "+minindex0);
        map_1.put("avgtraveltime",avgtraveltime0);
        map_1.put("id",list.get(0).get("id").toString());
        map_1.put("name",list.get(0).get("name").toString());

        map_2.put("time",timeB);
        map_2.put("avgspeed",avgspeed1);
        map_2.put("maxminspeed",maxspeed1+" & "+minspeed1);
        map_2.put("avgindex",avgindex1);
        map_2.put("maxminindex",maxindex1+" & "+minindex1);
        map_2.put("avgtraveltime",avgtraveltime1);
        map_2.put("id",list.get(1).get("id").toString());
        map_2.put("name",list.get(1).get("name").toString());

        map_3.put("time","对比结果");
        map_3.put("avgspeed",avgspeedResult);
        map_3.put("maxminspeed",maxspeedResult+" & "+minspeedResult);
        map_3.put("avgindex",avgindexResult);
        map_3.put("maxminindex",maxindexResult+" & "+minindexResult);
        map_3.put("avgtraveltime",avgtraveltimeResult);
        map_3.put("name",list.get(1).get("name").toString());

        maps.add(map_1);
        maps.add(map_2);
        maps.add(map_3);
        return maps;
    }
}
